<template>
  <div class="container">
    <h1>PDF转Word工具</h1>
    <div class="upload-area">
      <el-upload
        class="upload-component"
        drag
        action="#"
        :auto-upload="false"
        :show-file-list="false"
        accept=".pdf"
        @change="handleFileChange"
        @drop.prevent="handleDrop"
        @dragover.prevent="handleDragOver"
        @dragleave.prevent="handleDragLeave">
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖拽PDF文件到此处或 <em>点击上传</em>
        </div>
      </el-upload>
    </div>

    <div v-if="fileInfo" class="conversion-panel">
      <div class="file-info">
        <h3>文件信息</h3>
        <p>文件名: {{ fileInfo.name }}</p>
        <p>大小: {{ formatFileSize(fileInfo.size) }}</p>
      </div>

      <div class="conversion-controls">
        <el-button type="primary" @click="startConversion" :loading="converting">
          {{ converting ? '转换中...' : '开始转换' }}
        </el-button>
      </div>

      <div v-if="convertedFile" class="download-section">
        <el-alert
          title="转换完成！"
          type="success"
          :closable="false"
          show-icon
        />
        <el-button type="success" @click="downloadFile" class="download-btn">
          下载Word文件
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import * as pdfjsLib from 'pdfjs-dist'
import { Document, Paragraph, Packer, TextRun } from 'docx'

// 设置pdf.js worker
import workerUrl from '../assets/pdf.worker.min.mjs?url'
pdfjsLib.GlobalWorkerOptions.workerSrc = workerUrl

const fileInfo = ref(null)
const converting = ref(false)
const convertedFile = ref(null)

const handleFileChange = (file) => {
  const fileObj = file.raw
  if (!fileObj) return

  // 检查文件类型
  if (fileObj.type !== 'application/pdf') {
    ElMessage.error('请上传PDF文件！')
    return
  }

  // 保存文件信息
  fileInfo.value = {
    file: fileObj,
    name: fileObj.name,
    size: fileObj.size
  }
}

const startConversion = async () => {
  if (!fileInfo.value) {
    ElMessage.warning('请先上传PDF文件')
    return
  }

  converting.value = true
  try {
    const reader = new FileReader()
    reader.readAsArrayBuffer(fileInfo.value.file)

    const pdfData = await new Promise((resolve, reject) => {
      reader.onload = () => resolve(reader.result)
      reader.onerror = reject
    })

    // 加载PDF文件
    const loadingTask = pdfjsLib.getDocument({ data: pdfData })
    const pdf = await loadingTask.promise
    
    // 遍历所有页面并提取文本
    const paragraphs = []
    console.log(`开始处理PDF文件，总页数：${pdf.numPages}页`)
    
    for (let i = 1; i <= pdf.numPages; i++) {
      console.log(`正在处理第${i}页...`)
      const page = await pdf.getPage(i)
      const content = await page.getTextContent()
      console.log(`第${i}页文本项数量：${content.items.length}`)
      
      let currentParagraph = ''
      let lastY = null
      let lastFontName = null
      let lastFontSize = null
      
      // 根据位置信息和字体样式组织文本
      for (const item of content.items) {
        const fontName = item.fontName
        const fontSize = item.transform[0] // 字体大小通常存储在transform矩阵的第一个元素
        const y = item.transform[5]
        
        const isNewParagraph = lastY !== null && (
          Math.abs(y - lastY) > 3 || // 降低Y坐标差异阈值
          (fontName && lastFontName && fontName !== lastFontName) || // 字体变化
          (fontSize && lastFontSize && Math.abs(fontSize - lastFontSize) > 2) // 字号变化
        )
        
        if (isNewParagraph) {
          if (currentParagraph.trim()) {
            console.log(`添加段落(${currentParagraph.length}字符):`, 
              currentParagraph.substring(0, 30) + (currentParagraph.length > 30 ? '...' : ''))
            paragraphs.push(currentParagraph.trim())
          }
          currentParagraph = ''
        }
        
        // 处理文本内容
        let text = item.str
        if (item.hasEOL) {
          text += ' '
        }
        
        // 处理连续空格
        text = text.replace(/\s+/g, ' ')
        currentParagraph += text
        
        lastY = y
        lastFontName = fontName
        lastFontSize = fontSize
      }
      
      // 处理最后一个段落
      if (currentParagraph.trim()) {
        console.log(`添加最后一个段落(${currentParagraph.length}字符):`, 
          currentParagraph.substring(0, 30) + (currentParagraph.length > 30 ? '...' : ''))
        paragraphs.push(currentParagraph.trim())
      }
      
      console.log(`第${i}页处理完成，累计提取段落数：${paragraphs.length}`)
    }
    
    console.log(`文本提取完成，总共提取了${paragraphs.length}个段落`)
    if (paragraphs.length === 0) {
      throw new Error('未能从PDF中提取到文本内容，请确保PDF文件包含可提取的文本')
    }
    
    // 创建Word文档
    console.log('开始创建Word文档...')
    
    // 创建Word文档，保持段落格式
    if (paragraphs.length === 0) {
      throw new Error('未能从PDF中提取到文本内容')
    }
    
    // 确保有内容可以添加到Word文档中
    console.log('准备创建Word文档，段落数量:', paragraphs.length)
    
    const docx = new Document({
      sections: [{
        properties: {},
        children: paragraphs.map(text => {
          console.log('添加段落:', text.substring(0, 50) + (text.length > 50 ? '...' : ''))
          return new Paragraph({
            children: [new TextRun({
              text: text,
              size: 24, // 12pt
              font: 'Arial'
            })],
            spacing: {
              after: 200, // 段落后间距
              line: 360, // 1.5倍行距
              lineRule: 'auto'
            }
          })
        })
      }]
    })
    
    console.log('Word文档创建完成')

    // 生成Word文件
    console.log('开始生成Word文件Blob')
    try {
      const blob = await Packer.toBlob(docx)
      console.log('Blob生成成功，大小:', blob.size, 'bytes')
      convertedFile.value = {
        name: fileInfo.value.name.replace('.pdf', '.docx'),
        data: blob
      }
    } catch (packError) {
      console.error('生成Word文件失败:', packError)
      throw packError
    }

    ElMessage.success('转换成功！')
  } catch (error) {
    const errorMessage = error.message.includes('Failed to fetch') ? 
      '无法加载PDF处理组件，请检查网络连接' : 
      '转换失败，请重试'
    ElMessage.error(errorMessage)
    console.error('转换失败:', error)
  } finally {
    converting.value = false
  }
}

const downloadFile = () => {
  if (!convertedFile.value) return

  const link = document.createElement('a')
  link.href = URL.createObjectURL(convertedFile.value.data)
  link.download = convertedFile.value.name
  link.click()
}

const formatFileSize = (bytes) => {
  if (bytes < 1024) return bytes + ' B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
  return (bytes / (1024 * 1024)).toFixed(2) + ' MB'
}

const handleDrop = (e) => {
  e.stopPropagation()
  
  const files = e.dataTransfer.files
  if (files && files.length > 0) {
    const file = files[0]
    if (file.type !== 'application/pdf') {
      ElMessage.error('请上传PDF文件！')
      return
    }
    handleFileChange({ raw: file })
  }
  
  const uploadDragger = document.querySelector('.el-upload-dragger')
  if (uploadDragger) {
    uploadDragger.classList.remove('is-dragover')
    uploadDragger.style.cursor = ''
  }
}

const handleDragOver = (e) => {
  e.stopPropagation()
  
  const items = e.dataTransfer.items
  let isValid = false
  
  if (items && items.length > 0) {
    const item = items[0]
    isValid = item.kind === 'file' && item.type === 'application/pdf'
  }

  const uploadDragger = document.querySelector('.el-upload-dragger')
  if (uploadDragger) {
    if (isValid) {
      uploadDragger.classList.add('is-dragover')
      uploadDragger.style.cursor = 'copy'
    } else {
      uploadDragger.classList.remove('is-dragover')
      uploadDragger.style.cursor = 'no-drop'
    }
  }
}

const handleDragLeave = (e) => {
  const uploadDragger = document.querySelector('.el-upload-dragger')
  if (uploadDragger) {
    uploadDragger.classList.remove('is-dragover')
    uploadDragger.style.cursor = ''
  }
}
</script>

<style scoped>
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

h1 {
  text-align: center;
  margin-bottom: 30px;
}

.upload-area {
  margin-bottom: 30px;
}

.upload-component {
  width: 100%;
}

.upload-component :deep(.el-upload) {
  width: 100%;
}

.upload-component :deep(.el-upload-dragger) {
  width: 100%;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 2px dashed var(--el-border-color);
  border-radius: 8px;
  transition: all 0.3s;
}

.upload-component :deep(.el-upload-dragger:hover),
.upload-component :deep(.el-upload-dragger.is-dragover) {
  background-color: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary);
}

.upload-component :deep(.el-icon--upload) {
  font-size: 48px;
  color: var(--el-color-primary);
  margin-bottom: 16px;
}

.upload-component :deep(.el-upload__text) {
  color: var(--el-text-color-regular);
  font-size: 16px;
}

.upload-component :deep(.el-upload__text em) {
  color: var(--el-color-primary);
  font-style: normal;
  font-weight: bold;
}

.conversion-panel {
  background-color: #f5f7fa;
  padding: 20px;
  border-radius: 8px;
}

.file-info {
  margin-bottom: 20px;
  padding: 15px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.file-info h3 {
  margin: 0 0 10px 0;
}

.file-info p {
  margin: 5px 0;
  color: var(--el-text-color-regular);
}

.conversion-controls {
  text-align: center;
  margin: 20px 0;
}

.download-section {
  margin-top: 20px;
  text-align: center;
}

.download-btn {
  margin-top: 15px;
}
</style>